package com.zingrow.web.push.baidu.service.impl;

import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;

import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.fluent.Configurations;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.baidu.yun.core.log.YunLogEvent;
import com.baidu.yun.core.log.YunLogHandler;
import com.baidu.yun.push.auth.PushKeyPair;
import com.baidu.yun.push.client.BaiduPushClient;
import com.baidu.yun.push.constants.BaiduPushConstants;
import com.baidu.yun.push.exception.PushClientException;
import com.baidu.yun.push.exception.PushServerException;
import com.baidu.yun.push.model.PushMsgToAllRequest;
import com.baidu.yun.push.model.PushMsgToSingleDeviceRequest;
import com.baidu.yun.push.model.PushMsgToSingleDeviceResponse;
import com.baidu.yun.push.model.PushRequest;
import com.zingrow.web.push.baidu.model.BaiduPushKeyInfo;
import com.zingrow.web.push.baidu.model.PushMessageModel;
import com.zingrow.web.push.baidu.model.UserAppModel;
import com.zingrow.web.push.baidu.service.IAppPushService;

import net.sf.json.JSONObject;

/**
 * 手机推送
 * 
 * @author sywd
 *
 */
@Service
public class AppPushService implements IAppPushService {
	/**
	 * 日志工具
	 */
	private static Logger logger = LoggerFactory.getLogger(AppPushService.class);
	/**
	 * 保存百度推送的密钥信息.key为appid
	 */
	private static Map<String, BaiduPushKeyInfo> baiduPushKeyMap = new HashMap<String, BaiduPushKeyInfo>();
	/**
	 * 安卓设备
	 */
	private static Integer ANDROID_TYPE = 3;
	/**
	 * IOS设备
	 */
	private static Integer IOS_TYPE = 4;

	/**
	 * 初始化一些信息，如baiduPushKeyMap在这里必须进行初始化
	 */
	@PostConstruct
	private void init() {
		try {
			// 初始化baiduPushKeyMap
			Configurations configs = new Configurations();
			PropertiesConfiguration config = configs.properties(new File(this.getClass().getResource("/").getPath(), "properties/baidutuisong.properties"));
			String deployStatus = config.getString("push_deployStatus", "2");
			// Android
			BaiduPushKeyInfo info = new BaiduPushKeyInfo();
			info.setDeployStatus(Integer.parseInt(deployStatus));
			info.setAppId("8389244");
			info.setApiKey("LIGoGXb9YW9AITfjz0L6xDZo");
			info.setSecretKey("k0kReCqMNGFPGGmic1oGjM9h3vWt9Cor");
			baiduPushKeyMap.put(info.getAppId(), info);
			// IOS
			BaiduPushKeyInfo info2 = new BaiduPushKeyInfo();
			info2.setDeployStatus(Integer.parseInt(deployStatus));
			info2.setAppId("7938505");
			info2.setApiKey("eGRKcClpUulYM0jTzeMy7cGU");
			info2.setSecretKey("0SvoEM04lXQ8GqsXmqQp6Xe82HYr9s4G");
			baiduPushKeyMap.put(info2.getAppId(), info2);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.toString());
		}
		// 初始化android_type和ios_type
	}

	private ExecutorService pushExecPool = Executors.newFixedThreadPool(3);

	@Override
	public int pushNoticeMessage(final Set<UserAppModel> userAppModels, final PushMessageModel pushMessageModel) {
		// init();
		if (baiduPushKeyMap.size() <= 0 || ANDROID_TYPE == null || IOS_TYPE == null || userAppModels.size() <= 0
				|| StringUtils.isBlank(pushMessageModel.getTitle())) {
			return 0;
		}
		pushExecPool.execute(new Runnable() {
			@Override
			public void run() {
				doPush(userAppModels, pushMessageModel);
			}
		});
		return 1;
	}

	/**
	 * 执行推送
	 * 
	 * @param userAppModels
	 * @param pushMessageModel
	 */
	private void doPush(Set<UserAppModel> userAppModels, PushMessageModel pushMessageModel) {
		for (UserAppModel userAppModel : userAppModels) {
			// 这里基本执行单播
			if (userAppModel.getAppId() == null || userAppModel.getAppChannelId() == null
					|| userAppModel.getAppDeviceType() == null) {
				continue;
			}
			BaiduPushKeyInfo info = baiduPushKeyMap.get(userAppModel.getAppId());
			if (info == null) {
				continue;
			}
			if (userAppModel.getAppDeviceType() == ANDROID_TYPE) {
				pushNotice2Android(userAppModel, pushMessageModel, info);
			} else if (userAppModel.getAppDeviceType() == IOS_TYPE && info.getDeployStatus() != null) {
				pushNotice2IOS(userAppModel, pushMessageModel, info);
			}
		}
	}

	/**
	 * 推送安卓通知消息
	 * 
	 * @param userAppModel
	 * @param pushMessageModel
	 */
	private void pushNotice2Android(UserAppModel userAppModel, PushMessageModel pushMessageModel,
			BaiduPushKeyInfo info) {
		// 构建json消息体
		JSONObject contentJson = new JSONObject();
		if (pushMessageModel.getContentMap() != null) {
			for (String key : pushMessageModel.getContentMap().keySet()) {
				contentJson.put(key, pushMessageModel.getContentMap().get(key));
			}
		}
		JSONObject messageJson = new JSONObject();
		messageJson.put("title", pushMessageModel.getTitle());
		messageJson.put("description", pushMessageModel.getTitle());
		messageJson.put("custom_content", contentJson);
		// 构建request对象
		PushMsgToSingleDeviceRequest request = new PushMsgToSingleDeviceRequest().addMsgExpires(new Integer(3600))
				.addMessageType(1).addDeviceType(ANDROID_TYPE).addChannelId(userAppModel.getAppChannelId())
				.addMessage(messageJson.toString());
		PushKeyPair pair = new PushKeyPair(info.getApiKey(), info.getSecretKey());
		pushRequest(pair, request);

	}

	/**
	 * 推送安卓透传消息
	 * 
	 * @param userAppModel
	 * @param pushMessageModel
	 */
	@SuppressWarnings("unused")
	private void pushTransparent2Android(UserAppModel userAppModel, PushMessageModel pushMessageModel,
			BaiduPushKeyInfo info) {
		JSONObject contentJson = new JSONObject();
		if (pushMessageModel.getContentMap() != null) {
			for (String key : pushMessageModel.getContentMap().keySet()) {
				contentJson.put(key, pushMessageModel.getContentMap().get(key));
			}
		}
	}

	/**
	 * 推送IOS通知消息
	 * 
	 * @param userAppModel
	 * @param pushMessageModel
	 */
	private void pushNotice2IOS(UserAppModel userAppModel, PushMessageModel pushMessageModel, BaiduPushKeyInfo info) {
		JSONObject messageJson = new JSONObject();
		messageJson.put("alert", pushMessageModel.getTitle());
		messageJson.put("badge", userAppModel.getBadge());
		messageJson.put("sound", "default");
		JSONObject contentJson = new JSONObject();
		contentJson.put("aps", messageJson);
		if (pushMessageModel.getContentMap() != null) {
			for (String key : pushMessageModel.getContentMap().keySet()) {
				contentJson.put(key, pushMessageModel.getContentMap().get(key));
			}
		}
		// 构建request对象
		PushMsgToSingleDeviceRequest request = new PushMsgToSingleDeviceRequest().addMsgExpires(new Integer(3600))
				.addMessageType(1).addDeviceType(IOS_TYPE).addChannelId(userAppModel.getAppChannelId())
				.addMessage(contentJson.toString()).addDeployStatus(info.getDeployStatus());
		PushKeyPair pair = new PushKeyPair(info.getApiKey(), info.getSecretKey());
		pushRequest(pair, request);
	}

	/**
	 * 提交消息到百度云推送.提交成功不一定推送成功，可以再次尝试推送
	 * 
	 * @param pushKeyPair
	 *            密钥keypair
	 * @param pushRequest
	 *            提交的请求
	 * @return 提交是否成功
	 */
	private boolean pushRequest(PushKeyPair pair, PushRequest pushRequest) {
		// 创建推送的client,host为百度默认
		BaiduPushClient client = new BaiduPushClient(pair, BaiduPushConstants.CHANNEL_REST_URL);
		// register a YunLogHandler to get detail interacting information in
		// this request.
		client.setChannelLogHandler(new YunLogHandler() {
			@Override
			public void onHandle(YunLogEvent event) {
				// 并不做什么卵事
				// System.out.println(event.getMessage());
			}
		});
		// 开始提交推送消息
		try {
			// 单播
			if (pushRequest instanceof PushMsgToSingleDeviceRequest) {
				PushMsgToSingleDeviceResponse response = client
						.pushMsgToSingleDevice((PushMsgToSingleDeviceRequest) pushRequest);
				System.out.println("msgId: " + response.getMsgId() + ",sendTime: " + response.getSendTime() + " 推送成功！");
			} else {
				// 广播
				client.pushMsgToAll((PushMsgToAllRequest) pushRequest);
			}
			return true;
		} catch (PushClientException e) {
			if (BaiduPushConstants.ERROROPTTYPE) {
			} else {
				logger.error("推送设备出错:" + e.getMessage());
			}
		} catch (PushServerException e) {
			// e.printStackTrace();
			logger.error("用户已解绑ID");
			if (BaiduPushConstants.ERROROPTTYPE) {
			} else {
				logger.error("推送出错:" + String.format("requestId: %d, errorCode: %d, errorMsg: %s", e.getRequestId(),
						e.getErrorCode(), e.getErrorMsg()));
			}
		}
		return false;
	}

	public static void main(String[] args) {
		UserAppModel userAppModel = new UserAppModel();
		// userAppModel.setAppChannelId("4028337933526826780");
		userAppModel.setAppChannelId("3555320773569354361");
		userAppModel.setAppDeviceType(3);
		userAppModel.setAppId("8389244");
		Set<UserAppModel> set = new HashSet<>();
		set.add(userAppModel);
		PushMessageModel pushMessageModel = new PushMessageModel();
		pushMessageModel.setTitle("zzzzzzzz");

		IAppPushService appPushService = new AppPushService();
		System.out.println(appPushService.pushNoticeMessage(set, pushMessageModel));

	}

}
